#include "Camera.hpp"
#include "utilities.hpp"

Camera::Camera(float eyeFov, float aspectRatio)
    :orig(0, 0, 0),
    eyeFov(eyeFov),
    horizontal(aspectRatio * 2, 0, 0),
    vertical(0, 2, 0),
    lowLeftCorner(-aspectRatio, -1, -1)
{}

Camera::Camera(
    const Eigen::Vector3f& origin,
    const Eigen::Vector3f& lookAt,
    const Eigen::Vector3f& viewUp,
    float eyeFov,
    float aspectRatio,
    float apertureRadius,
    float focalDist
)
    :orig(origin),
    eyeFov(eyeFov),
    apertureRadius(apertureRadius)
{
    auto viewportHeight = tanf(deg2radians(eyeFov / 2)) * 2;
    auto viewportWidth = aspectRatio * viewportHeight;
    Eigen::Vector3f lookDir = (lookAt - origin).normalized();
    w = -lookDir;
    u = (viewUp.cross(w)).normalized();
    v = (w.cross(u)).normalized();
    horizontal = viewportWidth * u * focalDist;
    vertical = viewportHeight * v * focalDist;
    lowLeftCorner = origin + focalDist * lookDir - horizontal / 2 - vertical / 2;
}

Camera::~Camera() {}

// 通过矩阵变换来移动视角
void Camera::transform(const Eigen::Matrix4f& trans) {
    
}
// uv都在[0,1]中
Ray Camera::get_ray(float u, float v)const {
    float cosine = cosf(rand_float(0, 2 * pi));
    float sine = sinf(rand_float(0, 2 * pi));
    Eigen::Vector3f offset = cosine * this->u + sine * this->v;
    offset *= apertureRadius * rand_float(0, 1);
    Ray ray(orig + offset, (lowLeftCorner + u * horizontal + v * vertical - orig - offset).normalized());
    return ray;
}
// uv都在[0,1]中
Ray Camera::get_ray(Eigen::Vector2f uv)const {
    return get_ray(uv.x(), uv.y());
}

void Camera::set_eyeFov(float fov) {
    eyeFov = fov;
    float focalLength = tanf(deg2radians(fov/2));
}
void Camera::set_aspect_ratio(float ratio) {
    
}